home *** CD-ROM | disk | FTP | other *** search
Text File | 1988-02-28 | 56.4 KB | 2,137 lines |
- Path: uunet!tektronix!tekgen!tekred!games
- From: games@tekred.TEK.COM
- Newsgroups: comp.sources.games
- Subject: v04i003: cribbage - 4.3BSD cribbage game, Part01/02
- Message-ID: <2373@tekred.TEK.COM>
- Date: 31 Mar 88 21:54:15 GMT
- Sender: billr@tekred.TEK.COM
- Lines: 2126
- Approved: billr@saab.CNA.TEK.COM
-
- Submitted by: bostic@okeeffe.Berkeley.EDU (Keith Bostic)
- Comp.sources.games: Volume 4, Issue 3
- Archive-name: cribbage/Part01
-
- [Here is the legal source for the 4.3BSD cribbage game. Thanks
- to Keith Bostic at Berkeley for making this available. -br]
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 1 (of 2)."
- # Contents: README MANIFEST crib.c cribbage.6 cribbage.n cribcur.h
- # io.c score.c
- # Wrapped by billr@saab on Thu Mar 31 13:51:52 1988
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f README -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"README\"
- else
- echo shar: Extracting \"README\" \(466 characters\)
- sed "s/^X//" >README <<'END_OF_README'
- XThe Makefiles for these games require the "dm" program to install
- X-- we've written a dungeon master program (hasn't everybody?) and they
- Xexpect to have it around. They also require the "mkdep" program to
- Xcreate dependencies. You probably want to note in the posting that
- Xthe problems exist, and everybody should hack the Makefile.
- X
- XYour posting should credit Earl Cohen with writing the logic for cribbage,
- Xand Ken Arnold with doing the screen interface.
- X
- X--keith
- END_OF_README
- if test 466 -ne `wc -c <README`; then
- echo shar: \"README\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f MANIFEST -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"MANIFEST\"
- else
- echo shar: Extracting \"MANIFEST\" \(564 characters\)
- sed "s/^X//" >MANIFEST <<'END_OF_MANIFEST'
- X File Name Archive # Description
- X-----------------------------------------------------------
- X MANIFEST 1 This shipping list
- X Makefile 2
- X README 1
- X cards.c 2
- X crib.c 1
- X cribbage.6 1
- X cribbage.h 2
- X cribbage.n 1
- X cribcur.h 1
- X deck.h 2
- X extern.c 2
- X io.c 1
- X macro 2
- X score.c 1
- X support.c 2
- END_OF_MANIFEST
- if test 564 -ne `wc -c <MANIFEST`; then
- echo shar: \"MANIFEST\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f crib.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"crib.c\"
- else
- echo shar: Extracting \"crib.c\" \(13125 characters\)
- sed "s/^X//" >crib.c <<'END_OF_crib.c'
- X/*
- X * Copyright (c) 1980 Regents of the University of California.
- X * All rights reserved.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that this notice is preserved and that due credit is given
- X * to the University of California at Berkeley. The name of the University
- X * may not be used to endorse or promote products derived from this
- X * software without specific prior written permission. This software
- X * is provided ``as is'' without express or implied warranty.
- X */
- X
- X#ifndef lint
- Xchar copyright[] =
- X"@(#) Copyright (c) 1980 Regents of the University of California.\n\
- X All rights reserved.\n";
- X#endif /* not lint */
- X
- X#ifndef lint
- Xstatic char sccsid[] = "@(#)crib.c 5.2 (Berkeley) 3/10/88";
- X#endif /* not lint */
- X
- X# include <curses.h>
- X# include <signal.h>
- X# include "deck.h"
- X# include "cribbage.h"
- X# include "cribcur.h"
- X
- X
- X# define LOGFILE "/usr/games/lib/criblog"
- X# define INSTRCMD "ul /usr/games/lib/crib.instr | more -f"
- X
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X register char *p;
- X BOOLEAN playing;
- X char *s; /* for reading arguments */
- X char bust; /* flag for arg reader */
- X FILE *f;
- X FILE *fopen();
- X char *getline();
- X int bye();
- X
- X while (--argc > 0) {
- X if ((*++argv)[0] != '-') {
- X fprintf(stderr, "\n\ncribbage: usage is 'cribbage [-eqr]'\n");
- X exit(1);
- X }
- X bust = FALSE;
- X for (s = argv[0] + 1; *s != NULL; s++) {
- X switch (*s) {
- X case 'e':
- X explain = TRUE;
- X break;
- X case 'q':
- X quiet = TRUE;
- X break;
- X case 'r':
- X rflag = TRUE;
- X break;
- X default:
- X fprintf(stderr, "\n\ncribbage: usage is 'cribbage [-eqr]'\n");
- X exit(2);
- X break;
- X }
- X if (bust)
- X break;
- X }
- X }
- X
- X initscr();
- X signal(SIGINT, bye);
- X crmode();
- X noecho();
- X Playwin = subwin(stdscr, PLAY_Y, PLAY_X, 0, 0);
- X Tablewin = subwin(stdscr, TABLE_Y, TABLE_X, 0, PLAY_X);
- X Compwin = subwin(stdscr, COMP_Y, COMP_X, 0, TABLE_X + PLAY_X);
- X Msgwin = subwin(stdscr, MSG_Y, MSG_X, Y_MSG_START, SCORE_X + 1);
- X leaveok(Playwin, TRUE);
- X leaveok(Tablewin, TRUE);
- X leaveok(Compwin, TRUE);
- X clearok(stdscr, FALSE);
- X
- X if (!quiet) {
- X msg("Do you need instructions for cribbage? ");
- X if (getuchar() == 'Y') {
- X endwin();
- X fflush(stdout);
- X system(INSTRCMD);
- X crmode();
- X noecho();
- X clear();
- X refresh();
- X msg("For the rules of this program, do \"man cribbage\"");
- X }
- X }
- X playing = TRUE;
- X do {
- X wclrtobot(Msgwin);
- X msg(quiet ? "L or S? " : "Long (to 121) or Short (to 61)? ");
- X if (glimit == SGAME)
- X glimit = (getuchar() == 'L' ? LGAME : SGAME);
- X else
- X glimit = (getuchar() == 'S' ? SGAME : LGAME);
- X game();
- X msg("Another game? ");
- X playing = (getuchar() == 'Y');
- X } while (playing);
- X
- X if ((f = fopen(LOGFILE, "a")) != NULL) {
- X fprintf(f, "Won %5.5d, Lost %5.5d\n", cgames, pgames);
- X fclose(f);
- X }
- X
- X bye();
- X}
- X
- X/*
- X * makeboard:
- X * Print out the initial board on the screen
- X */
- Xmakeboard()
- X{
- X mvaddstr(SCORE_Y + 0, SCORE_X, "+---------------------------------------+");
- X mvaddstr(SCORE_Y + 1, SCORE_X, "| Score: 0 YOU |");
- X mvaddstr(SCORE_Y + 2, SCORE_X, "| *.....:.....:.....:.....:.....:..... |");
- X mvaddstr(SCORE_Y + 3, SCORE_X, "| *.....:.....:.....:.....:.....:..... |");
- X mvaddstr(SCORE_Y + 4, SCORE_X, "| |");
- X mvaddstr(SCORE_Y + 5, SCORE_X, "| *.....:.....:.....:.....:.....:..... |");
- X mvaddstr(SCORE_Y + 6, SCORE_X, "| *.....:.....:.....:.....:.....:..... |");
- X mvaddstr(SCORE_Y + 7, SCORE_X, "| Score: 0 ME |");
- X mvaddstr(SCORE_Y + 8, SCORE_X, "+---------------------------------------+");
- X gamescore();
- X}
- X
- X/*
- X * gamescore:
- X * Print out the current game score
- X */
- Xgamescore()
- X{
- X extern int Lastscore[];
- X
- X if (pgames || cgames) {
- X mvprintw(SCORE_Y + 1, SCORE_X + 28, "Games: %3d", pgames);
- X mvprintw(SCORE_Y + 7, SCORE_X + 28, "Games: %3d", cgames);
- X }
- X Lastscore[0] = -1;
- X Lastscore[1] = -1;
- X}
- X
- X/*
- X * game:
- X * Play one game up to glimit points. Actually, we only ASK the
- X * player what card to turn. We do a random one, anyway.
- X */
- Xgame()
- X{
- X register int i, j;
- X BOOLEAN flag;
- X BOOLEAN compcrib;
- X
- X makeboard();
- X refresh();
- X makedeck(deck);
- X shuffle(deck);
- X if (gamecount == 0) {
- X flag = TRUE;
- X do {
- X if (!rflag) { /* player cuts deck */
- X msg(quiet ? "Cut for crib? " :
- X "Cut to see whose crib it is -- low card wins? ");
- X getline();
- X }
- X i = (rand() >> 4) % CARDS; /* random cut */
- X do { /* comp cuts deck */
- X j = (rand() >> 4) % CARDS;
- X } while (j == i);
- X addmsg(quiet ? "You cut " : "You cut the ");
- X msgcard(deck[i], FALSE);
- X endmsg();
- X addmsg(quiet ? "I cut " : "I cut the ");
- X msgcard(deck[j], FALSE);
- X endmsg();
- X flag = (deck[i].rank == deck[j].rank);
- X if (flag) {
- X msg(quiet ? "We tied..." :
- X "We tied and have to try again...");
- X shuffle(deck);
- X continue;
- X }
- X else
- X compcrib = (deck[i].rank > deck[j].rank);
- X } while (flag);
- X }
- X else {
- X werase(Tablewin);
- X wrefresh(Tablewin);
- X werase(Compwin);
- X wrefresh(Compwin);
- X msg("Loser (%s) gets first crib", (iwon ? "you" : "me"));
- X compcrib = !iwon;
- X }
- X
- X pscore = cscore = 0;
- X flag = TRUE;
- X do {
- X shuffle(deck);
- X flag = !playhand(compcrib);
- X compcrib = !compcrib;
- X } while (flag);
- X ++gamecount;
- X if (cscore < pscore) {
- X if (glimit - cscore > 60) {
- X msg("YOU DOUBLE SKUNKED ME!");
- X pgames += 4;
- X }
- X else if (glimit - cscore > 30) {
- X msg("YOU SKUNKED ME!");
- X pgames += 2;
- X }
- X else {
- X msg("YOU WON!");
- X ++pgames;
- X }
- X iwon = FALSE;
- X }
- X else {
- X if (glimit - pscore > 60) {
- X msg("I DOUBLE SKUNKED YOU!");
- X cgames += 4;
- X }
- X else if (glimit - pscore > 30) {
- X msg("I SKUNKED YOU!");
- X cgames += 2;
- X }
- X else {
- X msg("I WON!");
- X ++cgames;
- X }
- X iwon = TRUE;
- X }
- X gamescore();
- X}
- X
- X/*
- X * playhand:
- X * Do up one hand of the game
- X */
- Xplayhand(mycrib)
- XBOOLEAN mycrib;
- X{
- X register int deckpos;
- X extern char Msgbuf[];
- X
- X werase(Compwin);
- X
- X knownum = 0;
- X deckpos = deal(mycrib);
- X sorthand(chand, FULLHAND);
- X sorthand(phand, FULLHAND);
- X makeknown(chand, FULLHAND);
- X prhand(phand, FULLHAND, Playwin, FALSE);
- X discard(mycrib);
- X if (cut(mycrib, deckpos))
- X return TRUE;
- X if (peg(mycrib))
- X return TRUE;
- X werase(Tablewin);
- X wrefresh(Tablewin);
- X if (score(mycrib))
- X return TRUE;
- X return FALSE;
- X}
- X
- X
- X
- X/*
- X * deal cards to both players from deck
- X */
- X
- Xdeal( mycrib )
- X{
- X register int i, j;
- X
- X j = 0;
- X for( i = 0; i < FULLHAND; i++ ) {
- X if( mycrib ) {
- X phand[i] = deck[j++];
- X chand[i] = deck[j++];
- X }
- X else {
- X chand[i] = deck[j++];
- X phand[i] = deck[j++];
- X }
- X }
- X return( j );
- X}
- X
- X/*
- X * discard:
- X * Handle players discarding into the crib...
- X * Note: we call cdiscard() after prining first message so player doesn't wait
- X */
- Xdiscard(mycrib)
- XBOOLEAN mycrib;
- X{
- X register char *prompt;
- X CARD crd;
- X
- X prcrib(mycrib, TRUE);
- X prompt = (quiet ? "Discard --> " : "Discard a card --> ");
- X cdiscard(mycrib); /* puts best discard at end */
- X crd = phand[infrom(phand, FULLHAND, prompt)];
- X remove(crd, phand, FULLHAND);
- X prhand(phand, FULLHAND, Playwin, FALSE);
- X crib[0] = crd;
- X/* next four lines same as last four except for cdiscard() */
- X crd = phand[infrom(phand, FULLHAND - 1, prompt)];
- X remove(crd, phand, FULLHAND - 1);
- X prhand(phand, FULLHAND, Playwin, FALSE);
- X crib[1] = crd;
- X crib[2] = chand[4];
- X crib[3] = chand[5];
- X chand[4].rank = chand[4].suit = chand[5].rank = chand[5].suit = EMPTY;
- X}
- X
- X/*
- X * cut:
- X * Cut the deck and set turnover. Actually, we only ASK the
- X * player what card to turn. We do a random one, anyway.
- X */
- Xcut(mycrib, pos)
- XBOOLEAN mycrib;
- Xint pos;
- X{
- X register int i, cardx;
- X BOOLEAN win = FALSE;
- X
- X if (mycrib) {
- X if (!rflag) { /* random cut */
- X msg(quiet ? "Cut the deck? " :
- X "How many cards down do you wish to cut the deck? ");
- X getline();
- X }
- X i = (rand() >> 4) % (CARDS - pos);
- X turnover = deck[i + pos];
- X addmsg(quiet ? "You cut " : "You cut the ");
- X msgcard(turnover, FALSE);
- X endmsg();
- X if (turnover.rank == JACK) {
- X msg("I get two for his heels");
- X win = chkscr(&cscore,2 );
- X }
- X }
- X else {
- X i = (rand() >> 4) % (CARDS - pos) + pos;
- X turnover = deck[i];
- X addmsg(quiet ? "I cut " : "I cut the ");
- X msgcard(turnover, FALSE);
- X endmsg();
- X if (turnover.rank == JACK) {
- X msg("You get two for his heels");
- X win = chkscr(&pscore, 2);
- X }
- X }
- X makeknown(&turnover, 1);
- X prcrib(mycrib, FALSE);
- X return win;
- X}
- X
- X/*
- X * prcrib:
- X * Print out the turnover card with crib indicator
- X */
- Xprcrib(mycrib, blank)
- XBOOLEAN mycrib, blank;
- X{
- X register int y, cardx;
- X
- X if (mycrib)
- X cardx = CRIB_X;
- X else
- X cardx = 0;
- X
- X mvaddstr(CRIB_Y, cardx + 1, "CRIB");
- X prcard(stdscr, CRIB_Y + 1, cardx, turnover, blank);
- X
- X if (mycrib)
- X cardx = 0;
- X else
- X cardx = CRIB_X;
- X
- X for (y = CRIB_Y; y <= CRIB_Y + 5; y++)
- X mvaddstr(y, cardx, " ");
- X}
- X
- X/*
- X * peg:
- X * Handle all the pegging...
- X */
- X
- Xstatic CARD Table[14];
- X
- Xstatic int Tcnt;
- X
- Xpeg(mycrib)
- XBOOLEAN mycrib;
- X{
- X static CARD ch[CINHAND], ph[CINHAND];
- X CARD crd;
- X register int i, j, k;
- X register int l;
- X register int cnum, pnum, sum;
- X register BOOLEAN myturn, mego, ugo, last, played;
- X
- X cnum = pnum = CINHAND;
- X for (i = 0; i < CINHAND; i++) { /* make copies of hands */
- X ch[i] = chand[i];
- X ph[i] = phand[i];
- X }
- X Tcnt = 0; /* index to table of cards played */
- X sum = 0; /* sum of cards played */
- X mego = ugo = FALSE;
- X myturn = !mycrib;
- X for (;;) {
- X last = TRUE; /* enable last flag */
- X prhand(ph, pnum, Playwin, FALSE);
- X prhand(ch, cnum, Compwin, TRUE);
- X prtable(sum);
- X if (myturn) { /* my tyrn to play */
- X if (!anymove(ch, cnum, sum)) { /* if no card to play */
- X if (!mego && cnum) { /* go for comp? */
- X msg("GO");
- X mego = TRUE;
- X }
- X if (anymove(ph, pnum, sum)) /* can player move? */
- X myturn = !myturn;
- X else { /* give him his point */
- X msg(quiet ? "You get one" : "You get one point");
- X if (chkscr(&pscore, 1))
- X return TRUE;
- X sum = 0;
- X mego = ugo = FALSE;
- X Tcnt = 0;
- X }
- X }
- X else {
- X played = TRUE;
- X j = -1;
- X k = 0;
- X for (i = 0; i < cnum; i++) { /* maximize score */
- X l = pegscore(ch[i], Table, Tcnt, sum);
- X if (l > k) {
- X k = l;
- X j = i;
- X }
- X }
- X if (j < 0) /* if nothing scores */
- X j = cchose(ch, cnum, sum);
- X crd = ch[j];
- X remove(crd, ch, cnum--);
- X sum += VAL(crd.rank);
- X Table[Tcnt++] = crd;
- X if (k > 0) {
- X addmsg(quiet ? "I get %d playing " :
- X "I get %d points playing ", k);
- X msgcard(crd, FALSE);
- X endmsg();
- X if (chkscr(&cscore, k))
- X return TRUE;
- X }
- X myturn = !myturn;
- X }
- X }
- X else {
- X if (!anymove(ph, pnum, sum)) { /* can player move? */
- X if (!ugo && pnum) { /* go for player */
- X msg("You have a GO");
- X ugo = TRUE;
- X }
- X if (anymove(ch, cnum, sum)) /* can computer play? */
- X myturn = !myturn;
- X else {
- X msg(quiet ? "I get one" : "I get one point");
- X do_wait();
- X if (chkscr(&cscore, 1))
- X return TRUE;
- X sum = 0;
- X mego = ugo = FALSE;
- X Tcnt = 0;
- X }
- X }
- X else { /* player plays */
- X played = FALSE;
- X if (pnum == 1) {
- X crd = ph[0];
- X msg("You play your last card");
- X }
- X else
- X for (;;) {
- X prhand(ph, pnum, Playwin, FALSE);
- X crd = ph[infrom(ph, pnum, "Your play: ")];
- X if (sum + VAL(crd.rank) <= 31)
- X break;
- X else
- X msg("Total > 31 -- try again");
- X }
- X makeknown(&crd, 1);
- X remove(crd, ph, pnum--);
- X i = pegscore(crd, Table, Tcnt, sum);
- X sum += VAL(crd.rank);
- X Table[Tcnt++] = crd;
- X if (i > 0) {
- X msg(quiet ? "You got %d" : "You got %d points", i);
- X if (chkscr(&pscore, i))
- X return TRUE;
- X }
- X myturn = !myturn;
- X }
- X }
- X if (sum >= 31) {
- X if (!myturn)
- X do_wait();
- X sum = 0;
- X mego = ugo = FALSE;
- X Tcnt = 0;
- X last = FALSE; /* disable last flag */
- X }
- X if (!pnum && !cnum)
- X break; /* both done */
- X }
- X prhand(ph, pnum, Playwin, FALSE);
- X prhand(ch, cnum, Compwin, TRUE);
- X prtable(sum);
- X if (last)
- X if (played) {
- X msg(quiet ? "I get one for last" : "I get one point for last");
- X do_wait();
- X if (chkscr(&cscore, 1))
- X return TRUE;
- X }
- X else {
- X msg(quiet ? "You get one for last" :
- X "You get one point for last");
- X if (chkscr(&pscore, 1))
- X return TRUE;
- X }
- X return FALSE;
- X}
- X
- X/*
- X * prtable:
- X * Print out the table with the current score
- X */
- Xprtable(score)
- Xint score;
- X{
- X prhand(Table, Tcnt, Tablewin, FALSE);
- X mvwprintw(Tablewin, (Tcnt + 2) * 2, Tcnt + 1, "%2d", score);
- X wrefresh(Tablewin);
- X}
- X
- X/*
- X * score:
- X * Handle the scoring of the hands
- X */
- Xscore(mycrib)
- XBOOLEAN mycrib;
- X{
- X sorthand(crib, CINHAND);
- X if (mycrib) {
- X if (plyrhand(phand, "hand"))
- X return TRUE;
- X if (comphand(chand, "hand"))
- X return TRUE;
- X do_wait();
- X if (comphand(crib, "crib"))
- X return TRUE;
- X }
- X else {
- X if (comphand(chand, "hand"))
- X return TRUE;
- X if (plyrhand(phand, "hand"))
- X return TRUE;
- X if (plyrhand(crib, "crib"))
- X return TRUE;
- X }
- X return FALSE;
- X}
- END_OF_crib.c
- if test 13125 -ne `wc -c <crib.c`; then
- echo shar: \"crib.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f cribbage.6 -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"cribbage.6\"
- else
- echo shar: Extracting \"cribbage.6\" \(4611 characters\)
- sed "s/^X//" >cribbage.6 <<'END_OF_cribbage.6'
- X.\" Copyright (c) 1980 Regents of the University of California.
- X.\" All rights reserved.
- X.\"
- X.\" Redistribution and use in source and binary forms are permitted
- X.\" provided that this notice is preserved and that due credit is given
- X.\" to the University of California at Berkeley. The name of the University
- X.\" may not be used to endorse or promote products derived from this
- X.\" software without specific prior written permission. This software
- X.\" is provided ``as is'' without express or implied warranty.
- X.\"
- X.\" @(#)cribbage.6 6.3 (Berkeley) 3/10/88
- X.\"
- X.TH CRIBBAGE 6 "March 10, 1988"
- X.UC 4
- X.SH NAME
- Xcribbage \- the card game cribbage
- X.SH SYNOPSIS
- X.B /usr/games/cribbage
- X[
- X.B \-req
- X]
- X.I name ...
- X.SH DESCRIPTION
- X.I Cribbage
- Xplays the card game cribbage, with the program playing one hand
- Xand the user the other. The program will initially ask the user if
- Xthe rules of the game are needed \- if so, it will print out
- Xthe appropriate section from
- X.I According to Hoyle
- Xwith
- X.I more (I).
- X.PP
- X.I Cribbage
- Xoptions include:
- X.TP
- X.B \-e
- XWhen the player makes a mistake scoring his hand or crib, provide an
- Xexplanation of the correct score. (This is especially useful for
- Xbeginning players.)
- X.TP
- X.B \-q
- XPrint a shorter form of all messages \- this is only recommended for
- Xusers who have played the game without specifying this option.
- X.TP
- X.B \-r
- XInstead of asking the player to cut the deck, the program will randomly
- Xcut the deck.
- X.PP
- X.I Cribbage
- Xfirst asks the player whether he wishes to play a short game
- X(\*(lqonce around\*(rq, to 61) or a long game (\*(lqtwice around\*(rq, to 121). A
- Xresponse of `s' will result in a short game, any other response will
- Xplay a long game.
- X.PP
- XAt the start of the first game, the program
- Xasks the player to cut the deck to determine who gets the
- Xfirst crib. The user should respond with a number between 0 and
- X51, indicating how many cards down the deck is to be cut. The player
- Xwho cuts the lower ranked card gets the first crib.
- XIf more than one game is played, the
- Xloser of the previous game gets the first crib in the current game.
- X.PP
- XFor each hand, the program first prints the player's hand,
- Xwhose crib it is, and then asks the player
- Xto discard two cards into the crib. The cards are prompted for
- Xone per line, and are typed as explained below.
- X.PP
- XAfter discarding, the program cuts the deck (if it is the player's
- Xcrib) or asks the player to cut the deck (if it's its crib); in the latter
- Xcase, the appropriate response is a number from 0 to 39 indicating
- Xhow far down the remaining 40 cards are to be cut.
- X.PP
- XAfter cutting the deck, play starts with the non-dealer (the person
- Xwho doesn't have the crib) leading the first card.
- XPlay continues, as per cribbage, until all cards are exhausted. The
- Xprogram keeps track of the scoring of all points and the total of
- Xthe cards on the table.
- X.PP
- XAfter play, the hands are scored. The program requests the player to
- Xscore his hand (and the crib, if it is his) by printing out the
- Xappropriate cards (and the cut card enclosed in brackets).
- XPlay continues until one player reaches the game limit (61 or 121).
- X.PP
- XA carriage return when a numeric input is expected is equivalent
- Xto typing the lowest legal value; when cutting the deck this
- Xis equivalent to choosing the top card.
- X.PP
- XCards are specified as rank followed by suit. The ranks may be specified
- Xas one of:
- X`a', `2', `3', `4', `5', `6', `7', `8', `9', `t', `j', `q', and `k',
- Xor alternatively, one of: \*(lqace\*(rq, \*(lqtwo\*(rq, \*(lqthree\*(rq, \*(lqfour\*(rq, \*(lqfive\*(rq, \*(lqsix\*(rq,
- X\*(lqseven\*(rq, \*(lqeight\*(rq, \*(lqnine\*(rq, \*(lqten\*(rq, \*(lqjack\*(rq, \*(lqqueen\*(rq, and \*(lqking\*(rq.
- XSuits may be specified as: `s', `h', `d', and `c', or alternatively as:
- X\*(lqspades\*(rq, \*(lqhearts\*(rq, \*(lqdiamonds\*(rq, and \*(lqclubs\*(rq.
- XA card may be specified as: <rank> \*(lq \*(rq <suit>, or: <rank> \*(lq of \*(rq <suit>.
- XIf the single letter rank and suit designations are used, the space
- Xseparating the suit and rank may be left out. Also, if only one card
- Xof the desired rank is playable, typing the rank is sufficient.
- XFor example, if your hand was \*(lq2H, 4D, 5C, 6H, JC, KD\*(rq and it was
- Xdesired to discard the king of diamonds, any of the following could be typed:
- X\*(lqk\*(rq, \*(lqking\*(rq, \*(lqkd\*(rq, \*(lqk d\*(rq, \*(lqk of d\*(rq, \*(lqking d\*(rq, \*(lqking of d\*(rq, \*(lqk diamonds\*(rq,
- X\*(lqk of diamonds\*(rq, \*(lqking diamonds\*(rq, or \*(lqking of diamonds\*(rq.
- X.SH FILES
- X.ta 2i
- X/usr/games/cribbage
- X.SH AUTHORS
- XEarl T. Cohen wrote the logic.
- XKen Arnold added the screen oriented interface.
- END_OF_cribbage.6
- if test 4611 -ne `wc -c <cribbage.6`; then
- echo shar: \"cribbage.6\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f cribbage.n -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"cribbage.n\"
- else
- echo shar: Extracting \"cribbage.n\" \(10652 characters\)
- sed "s/^X//" >cribbage.n <<'END_OF_cribbage.n'
- X.\" Copyright (c) 1980 Regents of the University of California.
- X.\" All rights reserved. The Berkeley software License Agreement
- X.\" specifies the terms and conditions for redistribution.
- X.\"
- X.\" @(#)cribbage.n 5.1 (Berkeley) 5/30/85
- X.\"
- X.so macro
- X.na
- X.PH "CRIBBAGE"
- X.sp 2
- X.ce
- Xfrom
- X.sp
- X.ce
- X.ul
- XAccording to Hoyle
- X.sp 2
- X.PG
- XCribbage is believed to have been invented by Sir John Suckling (1609-1642).
- XProbably it is an elaboration of an older game, Noddy. The original game was
- Xplayed with hands of five cards; the modern game gives each player six. That
- Xis virtually the only change from Suckling's directions.
- X.HP "Players."
- XTwo. There are variants for three and four players, described later.
- X.HP "Cards."
- XThe pack of 52. The cards in each suit rank: K (high), Q, J, 10, 9, 8,
- X7, 6, 5, 4, 3, 2, A. The
- X.ul
- Xcounting values
- Xare: K, Q, J, 10, each 10 (wherefore these are called
- X.ul
- Xtenth cards);
- Xace, 1; each other card, its index value.
- X.HP "Cribbage Board".
- XIndispensable to scoring (unless you have a computer!, ed.) is the device
- Xknown as the
- X.ul
- Xcribbage board.
- XThis is a rectangular panel, long and narrow, in which are
- Xfour rows of 30 holes each. (See illustration.) At one end, or in the center,
- Xare two or four additional holes, called
- X.ul
- Xgame holes.
- XThe board is placed between the two players, and each keeps his own score on
- Xthe two rows of holes nearest himself. Each is supplied with two
- X.ul
- Xpegs.
- XBefore the first hand, the pegs are placed in the game holes. On
- Xmaking his first score, the player advances one peg an appropriate number
- Xof holes (one per point) away from the
- X.ul
- Xgame end
- Xof the board. The second score is recorded by placing the second peg an
- Xappropriate distance ahead of the first. For each subsequent score, the
- Xrear peg is jumped ahead of the other, the distance between the two pegs
- Xalways showing the amount of this last score.
- X.PG
- XThe traditional mode of scoring is down (away from the game end) the
- Xouter row, and up the inner row. "Once around" is a game of 61 points.
- X"Twice around" is a game of 121 points.
- X.HP "Preliminaries."
- XCards are drawn; the lower deals first. If cards of equal rank are drawn,
- Xboth players draw again. Dealer has the right to shuffle last. Nondealer
- Xcuts, and must leave at least four cards in each packet.
- X.HP "Dealing."
- XEach player receives six cards, dealt one at a time face down, beginning
- Xwith the nondealer. The turn to deal alternates. The dealer has an
- Xadvantage.
- X.HP "Laying Away."
- XAfter seeing his hand, each player
- X.ul
- Xlays away
- Xtwo cards face down. The four cards laid away, placed in one pile, form the
- X.ul
- Xcrib.
- XThe crib counts for the dealer. Nondealer therefore tries to lay away
- X.ul
- Xbalking cards --
- Xcards that are least likely to create a score in the crib.
- X.HP "The Starter."
- XAfter both hands have laid away, nondealer lifts off a packet from the top
- Xof the
- X.ul
- Xstock
- X(the rest of the pack). Again, each packet must contain at least four cards.
- XDealer turns up the top card of the lower packer, which is then placed on
- Xtop of the stock when the packets are reunited. The card thus turned up is
- Xcalled
- X.ul
- X1 the starter.
- XIf it is a jack, dealer immediately pegs 2, called
- X.ul
- X2 for his heels.
- X.HP "The Play."
- XNondealer begins the play by laying a card from his hand face up on the
- Xtable, announcing its counting value. Dealer then shows a card, announcing
- Xthe total count of the two cards. Play continues in the same way, by
- Xalternate exposure of cards, each player announcing the new total count.
- XThe total may be carried only to 31, no further. If a player adds a card
- Xthat brings the total exactly to 31, he pegs 2. If a player is unable to
- Xplay another card without exceeding 31, he must say "Go," and his opponent
- Xpegs 1, but before doing so, opponent must lay down any additional cards he
- Xcan without exceeding 31. If such additional cards bring the total to
- Xexactly 31, he pegs 2 instead of 1.
- X.PG
- XWhenever a
- X.ul
- Xgo
- Xoccurs, the opponent of the player who played the last card must lead for a
- Xnew count starting at zero. Playing the last card of all counts as a go.
- X(Since nondealer makes the opening lead, dealer is bound to peg at least
- X1 in play.)
- X.PG
- XBesides pegging for 31 and go, the player may also peg for certain
- Xcombinations made in play, as follows:
- X.sp 2
- X.ti +4
- X.ul
- XFifteen.
- X.IP
- XMaking the count total 15 pegs 2.
- X.EP
- X.sp 2
- X.ti +4
- X.ul
- XPair.
- X.IP
- XPlaying a card of same rank as that previously played pegs 2. Playing
- Xa third card of the same rank makes
- X.ul
- Xpair royal
- Xand pegs 6. Playing the fourth card of the same rank makes
- X.ul
- Xdouble pair royal
- Xand pegs 12.
- X.PG
- XThe tenth cards pair strictly by rank, a king with a king, a queen with a
- Xqueen, and so on. (King and jack do not make a pair, although each has
- Xthe counting value 10.)
- X.EP
- X.sp 2
- X.ti +4
- X.ul
- XRun.
- X.IP
- XPlaying a card which, with the two or more played immediately previously,
- Xmakes a sequence of three or more cards, pegs 1 for each card in the
- X.ul
- Xrun.
- XRuns depend on rank alone; the suits do not matter. Nor does the score
- Xfor run depend upon playing the cards in strict sequence, so long as
- Xthe three or more last cards played can be arranged in a run.
- X.ul
- XExample:
- X7, 6, 8 played in that order score 3 for run; 5, 2, 4, 3 played in that order
- Xscore 4 for run.
- X.EP
- X.PG
- XAny of the foregoing combinations count, whether the cards are played
- Xalternately or one player plays several times in succession in consequence
- Xof a go. But a combination does not score if it is interrupted by a go.
- X.HP "Showing."
- XAfter the play, the hands are
- X.ul
- Xshown
- X(counted). Nondealer shows first, then dealer's hand, then crib.
- XThe starter is deemed to belong to each hand, so that each hand includes
- Xfive cards. Combinations of scoring value are as follows:
- X.sp 2
- X.ti +4
- X.ul
- XFifteen.
- X.IP
- XEach combinations of two or more cards that total fifteen scores 2.
- X.EP
- X.sp 2
- X.ti +4
- X.ul
- XPair.
- X.IP
- XEach pair of cards of the same rank scores 2.
- X.EP
- X.sp 2
- X.ti +4
- X.ul
- XRun.
- X.IP
- XEach combination of three or more cards in sequence scores 1 for each card
- Xin the run.
- X.EP
- X.sp 2
- X.ti +4
- X.ul
- XFlush.
- X.IP
- XFour cards of the same suit in hand score 4; four cards in hand or crib
- Xof same suit as the starter score 5. (No count for four-flush in crib.)
- X.EP
- X.sp 2
- X.ti +4
- X.ul
- XHis Nobs.
- X.IP
- XJack of same suit as the starter, in hand or crib, scores 1.
- X.EP
- X.PG
- XIt is important to note that every separate grouping of cards that makes
- Xa fifteen, pair, or run counts separately. Three of a kind,
- X.ul
- Xpair royal,
- Xcounts 6 because three sets of pairs can be made; similarly, four of a
- Xkind,
- X.ul
- Xdouble pair royal,
- Xcontain six pairs and count 12.
- X.PG
- XThe highest possible hand is J, 5, 5, 5 with the starter the 5 of the same
- Xsuit as the jack. There are four fifteens by combining the jack with a
- Xfive, four more by combinations of three fives (a total of 16 for fifteens);
- Xthe double pair royal adds 12 for a total of 28; and
- X.ul
- Xhis nobs
- Xadds 1 for a maximum score of 29. (the score of 2 for
- X.ul
- Xhis heels
- Xdoes not count in the total of the hand, since it is pegged before the play.)
- X.PG
- XA
- X.ul
- Xdouble run
- Xis a run with one card duplicated, as 4-3-3-2. Exclusive of fifteens, a
- Xdouble run of three cards counts 8; of four cards, 10. A
- X.ul
- Xtriple run
- Xis a run of three with one card triplicated, as K-K-K-Q-J. Exclusive of
- Xfifteens, it counts 15. A
- X.ul
- Xquadruple run
- Xis a run of three with two different cards duplicated, as the example
- X8-8-7-6-6 previously given. Exclusive of fifteens, it counts 16.
- X.PG
- XNo hand can be constructed that counts 19, 25, 26 or 27. A time-honored
- Xway of showing a hand with not a single counting combination is to say
- X"I have nineteen."
- X.PG
- XThe customary oder in showing is to count fifteens first, then runs, then
- Xpairs, but there is no compulsion of law.
- X.ul
- XExample:
- XA hand (with starter) of 9-6-5-4-4 will usually be counted "Fifteen 2,
- Xfifteen 4, fifteen 6 and double run makes 14," or simply "Fifteen 6 and
- X8 is 14."
- X.HP "Muggins."
- XThe hands and crib are counted aloud, and if a player claims a greater
- Xtotal than is due him, his opponent may require correction. In some
- Xlocalities, if a player claims less than is due, his opponent may say
- X"Muggins" and himself score the points overlooked.
- X.HP "Scoring."
- XThe usual
- X.ul
- Xgame
- Xis 121, but it may be set at 61 by agreement. Since the player wins
- Xwho first returns to the game hole by going "twice around," the scores
- Xmust be pegged strictly in order: his heels, pegging in play, non-dealer's
- Xhand, dealer's hand, crib. Thus, if nondealer goes out on showing his
- Xhand, he wins, even though dealer might have gone out with a greater
- Xtotal if allowed to count his hand and crib.
- X.PG
- XWhen the game of 121 is played for a stake, a player wins a single game
- Xif the loser makes 61 points or more. If the loser fails to reach
- X61, he is
- X.ul
- Xlurched,
- Xand the other wins a double game.
- X.HP "Irregularities."
- X.ul
- XMisdeal.
- XThere must be a new deal by the same dealer if a card is found faced in the
- Xpack, if a card is exposed in dealing, or if the pack be found imperfect.
- X.PG
- X.ul
- XWrong Number of Cards.
- XIf one hand (not crib) is found to have the wrong number of cards after
- Xlaying away for the crib, the other hand and crib being correct, the
- Xopponent may either demand a new deal or may peg 2 and rectify the
- Xhand. If the crib is incorrect, both hands being correct, nondealer
- Xpegs 2 and the crib is corrected.
- X.HP "Error in Pegging."
- XIf a player places a peg short of the amount to which he is entitled, he
- Xmay not correct his error after he has played the next card or after the
- Xcut for the next deal. If he pegs more than his announced score,
- Xthe error must be corrected on demand at any time before the cut for the
- Xnext deal and his opponent pegs 2.
- X.HP "Strategy."
- XThe best balking cards are kings and aces, because they have the least
- Xchance of producing sequences. Tenth cards are generally good, provided
- Xthat the two cards laid away are not too
- X.ul
- Xnear
- X(likely to make a sequence). When nothing better offers, give two
- X.ul
- Xwide
- Xcards -- at least three apart in rank.
- X.PG
- XProverbially the safest lead is a 4. The next card cannot make a 15.
- XLower cards are also safe from this point of view, but are better
- Xtreasured for go and 31. The most dangerous leads are 7 and 8, but
- Xmay be made to trap the opponent when they are backed with other
- Xclose cards. Generally speaking, play
- X.ul
- Xon
- X(toward a sequence) when you have close cards and
- X.ul
- Xoff
- Xwhen you do not. However, the state of the score is a consideration.
- XIf far behind, play on when there is any chance of building a score
- Xfor yourself; if well ahead, balk your opponent by playing off unless
- Xyou will surely peg as much as he by playing on.
- END_OF_cribbage.n
- if test 10652 -ne `wc -c <cribbage.n`; then
- echo shar: \"cribbage.n\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f cribcur.h -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"cribcur.h\"
- else
- echo shar: Extracting \"cribcur.h\" \(1451 characters\)
- sed "s/^X//" >cribcur.h <<'END_OF_cribcur.h'
- X/*
- X * Copyright (c) 1980 Regents of the University of California.
- X * All rights reserved.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that this notice is preserved and that due credit is given
- X * to the University of California at Berkeley. The name of the University
- X * may not be used to endorse or promote products derived from this
- X * software without specific prior written permission. This software
- X * is provided ``as is'' without express or implied warranty.
- X *
- X * @(#)cribcur.h 5.2 (Berkeley) 3/10/88
- X */
- X
- X# define PLAY_Y 15 /* size of player's hand window */
- X# define PLAY_X 12
- X# define TABLE_Y 21 /* size of table window */
- X# define TABLE_X 14
- X# define COMP_Y 15 /* size of computer's hand window */
- X# define COMP_X 12
- X# define Y_SCORE_SZ 9 /* Y size of score board */
- X# define X_SCORE_SZ 41 /* X size of score board */
- X# define SCORE_Y 0 /* starting position of scoring board */
- X# define SCORE_X (PLAY_X + TABLE_X + COMP_X)
- X# define CRIB_Y 17 /* position of crib (cut card) */
- X# define CRIB_X (PLAY_X + TABLE_X)
- X# define MSG_Y (LINES - (Y_SCORE_SZ + 1))
- X# define MSG_X (COLS - SCORE_X - 1)
- X# define Y_MSG_START (Y_SCORE_SZ + 1)
- X
- X# define PEG '*' /* what a peg looks like on the board */
- X
- Xextern WINDOW *Compwin; /* computer's hand window */
- Xextern WINDOW *Msgwin; /* message window */
- Xextern WINDOW *Playwin; /* player's hand window */
- Xextern WINDOW *Tablewin; /* table window */
- END_OF_cribcur.h
- if test 1451 -ne `wc -c <cribcur.h`; then
- echo shar: \"cribcur.h\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f io.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"io.c\"
- else
- echo shar: Extracting \"io.c\" \(11117 characters\)
- sed "s/^X//" >io.c <<'END_OF_io.c'
- X/*
- X * Copyright (c) 1980 Regents of the University of California.
- X * All rights reserved.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that this notice is preserved and that due credit is given
- X * to the University of California at Berkeley. The name of the University
- X * may not be used to endorse or promote products derived from this
- X * software without specific prior written permission. This software
- X * is provided ``as is'' without express or implied warranty.
- X */
- X
- X#ifndef lint
- Xstatic char sccsid[] = "@(#)io.c 5.3 (Berkeley) 3/10/88";
- X#endif /* not lint */
- X
- X# include <curses.h>
- X# include <ctype.h>
- X# include <signal.h>
- X# include "deck.h"
- X# include "cribbage.h"
- X# include "cribcur.h"
- X
- X# define LINESIZE 128
- X
- X# ifdef CTRL
- X# undef CTRL
- X# endif
- X# define CTRL(X) ('X' - 'A' + 1)
- X
- X# ifdef notdef /* defined in curses.h */
- X# define erasechar() _tty.sg_erase
- X# define killchar() _tty.sg_kill
- X# endif
- X
- Xchar linebuf[ LINESIZE ];
- X
- Xchar *rankname[ RANKS ] = { "ACE", "TWO", "THREE", "FOUR",
- X "FIVE", "SIX", "SEVEN", "EIGHT",
- X "NINE", "TEN", "JACK", "QUEEN",
- X "KING" };
- X
- Xchar *rankchar[ RANKS ] = { "A", "2", "3", "4", "5", "6", "7",
- X "8", "9", "T", "J", "Q", "K" };
- X
- Xchar *suitname[ SUITS ] = { "SPADES", "HEARTS", "DIAMONDS",
- X "CLUBS" };
- X
- Xchar *suitchar[ SUITS ] = { "S", "H", "D", "C" };
- X
- X
- X
- X/*
- X * msgcard:
- X * Call msgcrd in one of two forms
- X */
- Xmsgcard(c, brief)
- XCARD c;
- XBOOLEAN brief;
- X{
- X if (brief)
- X return msgcrd(c, TRUE, (char *) NULL, TRUE);
- X else
- X return msgcrd(c, FALSE, " of ", FALSE);
- X}
- X
- X
- X
- X/*
- X * msgcrd:
- X * Print the value of a card in ascii
- X */
- Xmsgcrd(c, brfrank, mid, brfsuit)
- XCARD c;
- Xchar *mid;
- XBOOLEAN brfrank, brfsuit;
- X{
- X if (c.rank == EMPTY || c.suit == EMPTY)
- X return FALSE;
- X if (brfrank)
- X addmsg("%1.1s", rankchar[c.rank]);
- X else
- X addmsg(rankname[c.rank]);
- X if (mid != NULL)
- X addmsg(mid);
- X if (brfsuit)
- X addmsg("%1.1s", suitchar[c.suit]);
- X else
- X addmsg(suitname[c.suit]);
- X return TRUE;
- X}
- X
- X/*
- X * printcard:
- X * Print out a card.
- X */
- Xprintcard(win, cardno, c, blank)
- XWINDOW *win;
- Xint cardno;
- XCARD c;
- XBOOLEAN blank;
- X{
- X prcard(win, cardno * 2, cardno, c, blank);
- X}
- X
- X/*
- X * prcard:
- X * Print out a card on the window at the specified location
- X */
- Xprcard(win, y, x, c, blank)
- XWINDOW *win;
- Xint y, x;
- XCARD c;
- XBOOLEAN blank;
- X{
- X if (c.rank == EMPTY)
- X return;
- X mvwaddstr(win, y + 0, x, "+-----+");
- X mvwaddstr(win, y + 1, x, "| |");
- X mvwaddstr(win, y + 2, x, "| |");
- X mvwaddstr(win, y + 3, x, "| |");
- X mvwaddstr(win, y + 4, x, "+-----+");
- X if (!blank) {
- X mvwaddch(win, y + 1, x + 1, rankchar[c.rank][0]);
- X waddch(win, suitchar[c.suit][0]);
- X mvwaddch(win, y + 3, x + 4, rankchar[c.rank][0]);
- X waddch(win, suitchar[c.suit][0]);
- X }
- X}
- X
- X/*
- X * prhand:
- X * Print a hand of n cards
- X */
- Xprhand(h, n, win, blank)
- XCARD h[];
- Xint n;
- XWINDOW *win;
- XBOOLEAN blank;
- X{
- X register int i;
- X
- X werase(win);
- X for (i = 0; i < n; i++)
- X printcard(win, i, *h++, blank);
- X wrefresh(win);
- X}
- X
- X
- X
- X/*
- X * infrom:
- X * reads a card, supposedly in hand, accepting unambigous brief
- X * input, returns the index of the card found...
- X */
- Xinfrom(hand, n, prompt)
- XCARD hand[];
- Xint n;
- Xchar *prompt;
- X{
- X register int i, j;
- X CARD crd;
- X
- X if (n < 1) {
- X printf("\nINFROM: %d = n < 1!!\n", n);
- X exit(74);
- X }
- X for (;;) {
- X msg(prompt);
- X if (incard(&crd)) { /* if card is full card */
- X if (!isone(crd, hand, n))
- X msg("That's not in your hand");
- X else {
- X for (i = 0; i < n; i++)
- X if (hand[i].rank == crd.rank &&
- X hand[i].suit == crd.suit)
- X break;
- X if (i >= n) {
- X printf("\nINFROM: isone or something messed up\n");
- X exit(77);
- X }
- X return i;
- X }
- X }
- X else /* if not full card... */
- X if (crd.rank != EMPTY) {
- X for (i = 0; i < n; i++)
- X if (hand[i].rank == crd.rank)
- X break;
- X if (i >= n)
- X msg("No such rank in your hand");
- X else {
- X for (j = i + 1; j < n; j++)
- X if (hand[j].rank == crd.rank)
- X break;
- X if (j < n)
- X msg("Ambiguous rank");
- X else
- X return i;
- X }
- X }
- X else
- X msg("Sorry, I missed that");
- X }
- X /* NOTREACHED */
- X}
- X
- X
- X
- X/*
- X * incard:
- X * Inputs a card in any format. It reads a line ending with a CR
- X * and then parses it.
- X */
- Xincard(crd)
- XCARD *crd;
- X{
- X char *getline();
- X register int i;
- X int rnk, sut;
- X char *line, *p, *p1;
- X BOOLEAN retval;
- X
- X retval = FALSE;
- X rnk = sut = EMPTY;
- X if (!(line = getline()))
- X goto gotit;
- X p = p1 = line;
- X while( *p1 != ' ' && *p1 != NULL ) ++p1;
- X *p1++ = NULL;
- X if( *p == NULL ) goto gotit;
- X /* IMPORTANT: no real card has 2 char first name */
- X if( strlen(p) == 2 ) { /* check for short form */
- X rnk = EMPTY;
- X for( i = 0; i < RANKS; i++ ) {
- X if( *p == *rankchar[i] ) {
- X rnk = i;
- X break;
- X }
- X }
- X if( rnk == EMPTY ) goto gotit; /* it's nothing... */
- X ++p; /* advance to next char */
- X sut = EMPTY;
- X for( i = 0; i < SUITS; i++ ) {
- X if( *p == *suitchar[i] ) {
- X sut = i;
- X break;
- X }
- X }
- X if( sut != EMPTY ) retval = TRUE;
- X goto gotit;
- X }
- X rnk = EMPTY;
- X for( i = 0; i < RANKS; i++ ) {
- X if( !strcmp( p, rankname[i] ) || !strcmp( p, rankchar[i] ) ) {
- X rnk = i;
- X break;
- X }
- X }
- X if( rnk == EMPTY ) goto gotit;
- X p = p1;
- X while( *p1 != ' ' && *p1 != NULL ) ++p1;
- X *p1++ = NULL;
- X if( *p == NULL ) goto gotit;
- X if( !strcmp( "OF", p ) ) {
- X p = p1;
- X while( *p1 != ' ' && *p1 != NULL ) ++p1;
- X *p1++ = NULL;
- X if( *p == NULL ) goto gotit;
- X }
- X sut = EMPTY;
- X for( i = 0; i < SUITS; i++ ) {
- X if( !strcmp( p, suitname[i] ) || !strcmp( p, suitchar[i] ) ) {
- X sut = i;
- X break;
- X }
- X }
- X if( sut != EMPTY ) retval = TRUE;
- Xgotit:
- X (*crd).rank = rnk;
- X (*crd).suit = sut;
- X return( retval );
- X}
- X
- X
- X
- X/*
- X * getuchar:
- X * Reads and converts to upper case
- X */
- Xgetuchar()
- X{
- X register int c;
- X
- X c = readchar();
- X if (islower(c))
- X c = toupper(c);
- X waddch(Msgwin, c);
- X return c;
- X}
- X
- X/*
- X * number:
- X * Reads in a decimal number and makes sure it is between "lo" and
- X * "hi" inclusive.
- X */
- Xnumber(lo, hi, prompt)
- Xint lo, hi;
- Xchar *prompt;
- X{
- X char *getline();
- X register char *p;
- X register int sum;
- X
- X sum = 0;
- X for (;;) {
- X msg(prompt);
- X if(!(p = getline()) || *p == NULL) {
- X msg(quiet ? "Not a number" : "That doesn't look like a number");
- X continue;
- X }
- X sum = 0;
- X
- X if (!isdigit(*p))
- X sum = lo - 1;
- X else
- X while (isdigit(*p)) {
- X sum = 10 * sum + (*p - '0');
- X ++p;
- X }
- X
- X if (*p != ' ' && *p != '\t' && *p != NULL)
- X sum = lo - 1;
- X if (sum >= lo && sum <= hi)
- X return sum;
- X if (sum == lo - 1)
- X msg("that doesn't look like a number, try again --> ");
- X else
- X msg("%d is not between %d and %d inclusive, try again --> ",
- X sum, lo, hi);
- X }
- X}
- X
- X/*
- X * msg:
- X * Display a message at the top of the screen.
- X */
- Xchar Msgbuf[BUFSIZ] = { '\0' };
- X
- Xint Mpos = 0;
- X
- Xstatic int Newpos = 0;
- X
- X/* VARARGS1 */
- Xmsg(fmt, args)
- Xchar *fmt;
- Xint args;
- X{
- X doadd(fmt, &args);
- X endmsg();
- X}
- X
- X/*
- X * addmsg:
- X * Add things to the current message
- X */
- X/* VARARGS1 */
- Xaddmsg(fmt, args)
- Xchar *fmt;
- Xint args;
- X{
- X doadd(fmt, &args);
- X}
- X
- X/*
- X * endmsg:
- X * Display a new msg.
- X */
- X
- Xint Lineno = 0;
- X
- Xendmsg()
- X{
- X register int len;
- X register char *mp, *omp;
- X static int lastline = 0;
- X
- X /*
- X * All messages should start with uppercase
- X */
- X mvaddch(lastline + Y_MSG_START, SCORE_X, ' ');
- X if (islower(Msgbuf[0]) && Msgbuf[1] != ')')
- X Msgbuf[0] = toupper(Msgbuf[0]);
- X mp = Msgbuf;
- X len = strlen(mp);
- X if (len / MSG_X + Lineno >= MSG_Y) {
- X while (Lineno < MSG_Y) {
- X wmove(Msgwin, Lineno++, 0);
- X wclrtoeol(Msgwin);
- X }
- X Lineno = 0;
- X }
- X mvaddch(Lineno + Y_MSG_START, SCORE_X, '*');
- X lastline = Lineno;
- X do {
- X mvwaddstr(Msgwin, Lineno, 0, mp);
- X if ((len = strlen(mp)) > MSG_X) {
- X omp = mp;
- X for (mp = &mp[MSG_X-1]; *mp != ' '; mp--)
- X continue;
- X while (*mp == ' ')
- X mp--;
- X mp++;
- X wmove(Msgwin, Lineno, mp - omp);
- X wclrtoeol(Msgwin);
- X }
- X if (++Lineno >= MSG_Y)
- X Lineno = 0;
- X } while (len > MSG_X);
- X wclrtoeol(Msgwin);
- X Mpos = len;
- X Newpos = 0;
- X wrefresh(Msgwin);
- X refresh();
- X wrefresh(Msgwin);
- X}
- X
- X/*
- X * doadd:
- X * Perform an add onto the message buffer
- X */
- Xdoadd(fmt, args)
- Xchar *fmt;
- Xint *args;
- X{
- X static FILE junk;
- X
- X /*
- X * Do the printf into Msgbuf
- X */
- X junk._flag = _IOWRT + _IOSTRG;
- X junk._ptr = &Msgbuf[Newpos];
- X junk._cnt = 32767;
- X _doprnt(fmt, args, &junk);
- X putc('\0', &junk);
- X Newpos = strlen(Msgbuf);
- X}
- X
- X/*
- X * do_wait:
- X * Wait for the user to type ' ' before doing anything else
- X */
- Xdo_wait()
- X{
- X register int line;
- X static char prompt[] = { '-', '-', 'M', 'o', 'r', 'e', '-', '-', '\0' };
- X
- X if (Mpos + sizeof prompt < MSG_X)
- X wmove(Msgwin, Lineno > 0 ? Lineno - 1 : MSG_Y - 1, Mpos);
- X else {
- X mvwaddch(Msgwin, Lineno, 0, ' ');
- X wclrtoeol(Msgwin);
- X if (++Lineno >= MSG_Y)
- X Lineno = 0;
- X }
- X waddstr(Msgwin, prompt);
- X wrefresh(Msgwin);
- X wait_for(' ');
- X}
- X
- X/*
- X * wait_for
- X * Sit around until the guy types the right key
- X */
- Xwait_for(ch)
- Xregister char ch;
- X{
- X register char c;
- X
- X if (ch == '\n')
- X while ((c = readchar()) != '\n')
- X continue;
- X else
- X while (readchar() != ch)
- X continue;
- X}
- X
- X/*
- X * readchar:
- X * Reads and returns a character, checking for gross input errors
- X */
- Xreadchar()
- X{
- X register int cnt, y, x;
- X auto char c;
- X
- Xover:
- X cnt = 0;
- X while (read(0, &c, 1) <= 0)
- X if (cnt++ > 100) /* if we are getting infinite EOFs */
- X bye(); /* quit the game */
- X if (c == CTRL(L)) {
- X wrefresh(curscr);
- X goto over;
- X }
- X if (c == '\r')
- X return '\n';
- X else
- X return c;
- X}
- X
- X/*
- X * getline:
- X * Reads the next line up to '\n' or EOF. Multiple spaces are
- X * compressed to one space; a space is inserted before a ','
- X */
- Xchar *
- Xgetline()
- X{
- X register char *sp;
- X register int c, oy, ox;
- X register WINDOW *oscr;
- X
- X oscr = stdscr;
- X stdscr = Msgwin;
- X getyx(stdscr, oy, ox);
- X refresh();
- X /*
- X * loop reading in the string, and put it in a temporary buffer
- X */
- X for (sp = linebuf; (c = readchar()) != '\n'; clrtoeol(), refresh()) {
- X if (c == -1)
- X continue;
- X else if (c == erasechar()) { /* process erase character */
- X if (sp > linebuf) {
- X register int i;
- X
- X sp--;
- X for (i = strlen(unctrl(*sp)); i; i--)
- X addch('\b');
- X }
- X continue;
- X }
- X else if (c == killchar()) { /* process kill character */
- X sp = linebuf;
- X move(oy, ox);
- X continue;
- X }
- X else if (sp == linebuf && c == ' ')
- X continue;
- X if (sp >= &linebuf[LINESIZE-1] || !(isprint(c) || c == ' '))
- X putchar(CTRL(G));
- X else {
- X if (islower(c))
- X c = toupper(c);
- X *sp++ = c;
- X addstr(unctrl(c));
- X Mpos++;
- X }
- X }
- X *sp = '\0';
- X stdscr = oscr;
- X return linebuf;
- X}
- X
- X/*
- X * bye:
- X * Leave the program, cleaning things up as we go.
- X */
- Xbye()
- X{
- X signal(SIGINT, SIG_IGN);
- X mvcur(0, COLS - 1, LINES - 1, 0);
- X fflush(stdout);
- X endwin();
- X putchar('\n');
- X exit(1);
- X}
- END_OF_io.c
- if test 11117 -ne `wc -c <io.c`; then
- echo shar: \"io.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f score.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"score.c\"
- else
- echo shar: Extracting \"score.c\" \(9414 characters\)
- sed "s/^X//" >score.c <<'END_OF_score.c'
- X/*
- X * Copyright (c) 1980 Regents of the University of California.
- X * All rights reserved.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that this notice is preserved and that due credit is given
- X * to the University of California at Berkeley. The name of the University
- X * may not be used to endorse or promote products derived from this
- X * software without specific prior written permission. This software
- X * is provided ``as is'' without express or implied warranty.
- X */
- X
- X#ifndef lint
- Xstatic char sccsid[] = "@(#)score.c 5.3 (Berkeley) 3/10/88";
- X#endif /* not lint */
- X
- X#include <stdio.h>
- X#include "deck.h"
- X#include "cribbage.h"
- X
- X
- X/*
- X * the following arrays give the sum of the scores of the (50 2)*48 = 58800
- X * hands obtainable for the crib given the two cards whose ranks index the
- X * array. the two arrays are for the case where the suits are equal and
- X * not equal respectively
- X */
- X
- Xlong crbescr[ 169 ] = {
- X -10000, 271827, 278883, 332319, 347769, 261129, 250653, 253203, 248259,
- X 243435, 256275, 237435, 231051, -10000, -10000, 412815, 295707, 349497,
- X 267519, 262521, 259695, 254019, 250047, 262887, 244047, 237663, -10000,
- X -10000, -10000, 333987, 388629, 262017, 266787, 262971, 252729, 254475,
- X 267315, 248475, 242091, -10000, -10000, -10000, -10000, 422097, 302787,
- X 256437, 263751, 257883, 254271, 267111, 248271, 241887, -10000, -10000,
- X -10000, -10000, -10000, 427677, 387837, 349173, 347985, 423861, 436701,
- X 417861, 411477, -10000, -10000, -10000, -10000, -10000, -10000, 336387,
- X 298851, 338667, 236487, 249327, 230487, 224103, -10000, -10000, -10000,
- X -10000, -10000, -10000, -10000, 408483, 266691, 229803, 246195, 227355,
- X 220971, -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000,
- X 300675, 263787, 241695, 226407, 220023, -10000, -10000, -10000, -10000,
- X -10000, -10000, -10000, -10000, -10000, 295635, 273543, 219771, 216939,
- X -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000,
- X -10000, 306519, 252747, 211431, -10000, -10000, -10000, -10000, -10000,
- X -10000, -10000, -10000, -10000, -10000, -10000, 304287, 262971, -10000,
- X -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000,
- X -10000, -10000, 244131, -10000, -10000, -10000, -10000, -10000, -10000,
- X -10000, -10000, -10000, -10000, -10000, -10000, -10000 };
- X
- Xlong crbnescr[ 169 ] = {
- X 325272, 260772, 267828, 321264, 336714, 250074, 239598, 242148, 237204,
- X 232380, 246348, 226380, 219996, -10000, 342528, 401760, 284652, 338442,
- X 256464, 251466, 248640, 242964, 238992, 252960, 232992, 226608, -10000,
- X -10000, 362280, 322932, 377574, 250962, 255732, 251916, 241674, 243420,
- X 257388, 237420, 231036, -10000, -10000, -10000, 360768, 411042, 291732,
- X 245382, 252696, 246828, 243216, 257184, 237216, 230832, -10000, -10000,
- X -10000, -10000, 528768, 416622, 376782, 338118, 336930, 412806, 426774,
- X 406806, 400422, -10000, -10000, -10000, -10000, -10000, 369864, 325332,
- X 287796, 327612, 225432, 239400, 219432, 213048, -10000, -10000, -10000,
- X -10000, -10000, -10000, 359160, 397428, 255636, 218748, 236268, 216300,
- X 209916, -10000, -10000, -10000, -10000, -10000, -10000, -10000, 331320,
- X 289620, 252732, 231768, 215352, 208968, -10000, -10000, -10000, -10000,
- X -10000, -10000, -10000, -10000, 325152, 284580, 263616, 208716, 205884,
- X -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000,
- X 321240, 296592, 241692, 200376, -10000, -10000, -10000, -10000, -10000,
- X -10000, -10000, -10000, -10000, -10000, 348600, 294360, 253044, -10000,
- X -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000,
- X -10000, 308664, 233076, -10000, -10000, -10000, -10000, -10000, -10000,
- X -10000, -10000, -10000, -10000, -10000, -10000, 295896 };
- X
- X
- Xstatic int ichoose2[ 5 ] = { 0, 0, 2, 6, 12 };
- Xstatic int pairpoints, runpoints; /* globals from pairuns */
- X
- X
- X/*
- X * scorehand:
- X * Score the given hand of n cards and the starter card.
- X * n must be <= 4
- X */
- Xscorehand(hand, starter, n, crb, do_explain)
- Xregister CARD hand[];
- XCARD starter;
- Xint n;
- XBOOLEAN crb; /* true if scoring crib */
- XBOOLEAN do_explain; /* true if must explain this hand */
- X{
- X CARD h[(CINHAND + 1)];
- X register int i, k;
- X register int score;
- X register BOOLEAN flag;
- X char buf[32];
- X
- X expl[0] = NULL; /* initialize explanation */
- X score = 0;
- X flag = TRUE;
- X k = hand[0].suit;
- X for (i = 0; i < n; i++) { /* check for flush */
- X flag = (flag && (hand[i].suit == k));
- X if (hand[i].rank == JACK) /* check for his nibs */
- X if (hand[i].suit == starter.suit) {
- X score++;
- X if (do_explain)
- X strcat(expl, "His Nobs");
- X }
- X h[i] = hand[i];
- X }
- X
- X if (flag && n >= CINHAND) {
- X if (do_explain && expl[0] != NULL)
- X strcat(expl, ", ");
- X if (starter.suit == k) {
- X score += 5;
- X if (do_explain)
- X strcat(expl, "Five-flush");
- X }
- X else if (!crb) {
- X score += 4;
- X if (do_explain && expl[0] != NULL)
- X strcat(expl, ", Four-flush");
- X else
- X strcpy(expl, "Four-flush");
- X }
- X }
- X
- X if (do_explain && expl[0] != NULL)
- X strcat(expl, ", ");
- X h[n] = starter;
- X sorthand(h, n + 1); /* sort by rank */
- X i = 2 * fifteens(h, n + 1);
- X score += i;
- X if (do_explain)
- X if (i > 0) {
- X (void)sprintf(buf, "%d points in fifteens", i);
- X strcat(expl, buf);
- X }
- X else
- X strcat(expl, "No fifteens");
- X i = pairuns(h, n + 1);
- X score += i;
- X if (do_explain)
- X if (i > 0) {
- X (void)sprintf(buf, ", %d points in pairs, %d in runs",
- X pairpoints, runpoints);
- X strcat(expl, buf);
- X }
- X else
- X strcat(expl, ", No pairs/runs");
- X return score;
- X}
- X
- X/*
- X * fifteens:
- X * Return number of fifteens in hand of n cards
- X */
- Xfifteens(hand, n)
- Xregister CARD hand[];
- Xint n;
- X{
- X register int *sp, *np;
- X register int i;
- X register CARD *endp;
- X static int sums[15], nsums[15];
- X
- X np = nsums;
- X sp = sums;
- X i = 16;
- X while (--i) {
- X *np++ = 0;
- X *sp++ = 0;
- X }
- X for (endp = &hand[n]; hand < endp; hand++) {
- X i = hand->rank + 1;
- X if (i > 10)
- X i = 10;
- X np = &nsums[i];
- X np[-1]++; /* one way to make this */
- X sp = sums;
- X while (i < 15) {
- X *np++ += *sp++;
- X i++;
- X }
- X sp = sums;
- X np = nsums;
- X i = 16;
- X while (--i)
- X *sp++ = *np++;
- X }
- X return sums[14];
- X}
- X
- X
- X
- X/*
- X * pairuns returns the number of points in the n card sorted hand
- X * due to pairs and runs
- X * this routine only works if n is strictly less than 6
- X * sets the globals pairpoints and runpoints appropriately
- X */
- X
- Xpairuns( h, n )
- X
- X CARD h[];
- X int n;
- X{
- X register int i;
- X int runlength, runmult, lastmult, curmult;
- X int mult1, mult2, pair1, pair2;
- X BOOLEAN run;
- X
- X run = TRUE;
- X runlength = 1;
- X mult1 = 1;
- X pair1 = -1;
- X mult2 = 1;
- X pair2 = -1;
- X curmult = runmult = 1;
- X for( i = 1; i < n; i++ ) {
- X lastmult = curmult;
- X if( h[i].rank == h[i - 1].rank ) {
- X if( pair1 < 0 ) {
- X pair1 = h[i].rank;
- X mult1 = curmult = 2;
- X }
- X else {
- X if( h[i].rank == pair1 ) {
- X curmult = ++mult1;
- X }
- X else {
- X if( pair2 < 0 ) {
- X pair2 = h[i].rank;
- X mult2 = curmult = 2;
- X }
- X else {
- X curmult = ++mult2;
- X }
- X }
- X }
- X if( i == (n - 1) && run ) {
- X runmult *= curmult;
- X }
- X }
- X else {
- X curmult = 1;
- X if( h[i].rank == h[i - 1].rank + 1 ) {
- X if( run ) {
- X ++runlength;
- X }
- X else {
- X if( runlength < 3 ) { /* only if old short */
- X run = TRUE;
- X runlength = 2;
- X runmult = 1;
- X }
- X }
- X runmult *= lastmult;
- X }
- X else {
- X if( run ) runmult *= lastmult; /* if just ended */
- X run = FALSE;
- X }
- X }
- X }
- X pairpoints = ichoose2[ mult1 ] + ichoose2[ mult2 ];
- X runpoints = ( runlength >= 3 ? runlength*runmult : 0 );
- X return( pairpoints + runpoints );
- X}
- X
- X
- X
- X/*
- X * pegscore tells how many points crd would get if played after
- X * the n cards in tbl during pegging
- X */
- X
- Xpegscore( crd, tbl, n, sum )
- X
- X CARD crd, tbl[];
- X int n;
- X int sum;
- X{
- X BOOLEAN got[ RANKS ];
- X register int i, j, scr;
- X int k, lo, hi;
- X
- X sum += VAL( crd.rank );
- X if( sum > 31 ) return( -1 );
- X if( sum == 31 || sum == 15 ) scr = 2;
- X else scr = 0;
- X if( !n ) return( scr );
- X j = 1;
- X while( ( crd.rank == tbl[n - j].rank ) && ( n - j >= 0 ) ) ++j;
- X if( j > 1 ) return( scr + ichoose2[j] );
- X if( n < 2 ) return( scr );
- X lo = hi = crd.rank;
- X for( i = 0; i < RANKS; i++ ) got[i] = FALSE;
- X got[ crd.rank ] = TRUE;
- X k = -1;
- X for( i = n - 1; i >= 0; --i ) {
- X if( got[ tbl[i].rank ] ) break;
- X got[ tbl[i].rank ] = TRUE;
- X if( tbl[i].rank < lo ) lo = tbl[i].rank;
- X if( tbl[i].rank > hi ) hi = tbl[i].rank;
- X for( j = lo; j <= hi; j++ ) if( !got[j] ) break;
- X if( j > hi ) k = hi - lo + 1;
- X }
- X if( k >= 3 ) return( scr + k );
- X else return( scr );
- X}
- X
- X
- X
- X/*
- X * adjust takes a two card hand that will be put in the crib
- X * and returns an adjusted normalized score for the number of
- X * points such a crib will get.
- X */
- X
- Xadjust( cb, tnv )
- X
- X CARD cb[], tnv;
- X{
- X int i, c0, c1;
- X long scr;
- X
- X c0 = cb[0].rank;
- X c1 = cb[1].rank;
- X if( c0 > c1 ) {
- X i = c0;
- X c0 = c1;
- X c1 = i;
- X }
- X if( cb[0].suit != cb[1].suit ) scr = crbnescr[ RANKS*c0 + c1 ];
- X else scr = crbescr[ RANKS*c0 + c1 ];
- X if( scr <= 0 ) {
- X printf( "\nADJUST: internal error %d %d\n", c0, c1 );
- X exit( 93 );
- X }
- X return( (scr + 29400)/58800 );
- X}
- X
- X
- X
- END_OF_score.c
- if test 9414 -ne `wc -c <score.c`; then
- echo shar: \"score.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- echo shar: End of archive 1 \(of 2\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 2 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked both archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-